package gugga.utils
{
	import flash.display.Sprite;
	import flash.events.Event;
	
	/**
	 * <code>DoLaterUtil</code> is an utility for executing a method after a specified number 
	 * of frames.
	 */
	public class DoLaterUtil
	{
		private static var mOnEnterFrameBeacon : Sprite;
		private static var mDoLaterMethods : Array;
		
		public static function doLater(
			aMethod : Function, 
			aArguments : Array, 
			aFramesDelay : Number, 
			aScopeObject : * = null) : void
		{
			if(!mOnEnterFrameBeacon)
			{
				mOnEnterFrameBeacon = new Sprite();
			}
			
			if(!mDoLaterMethods)
			{
				mDoLaterMethods = new Array();
			}
			
			var framesDelay : Number = 1;
			
			if(aFramesDelay)
			{
				framesDelay = aFramesDelay;
			}
			
			var doLaterMethodDescriptor : Object = {
				scopeObject: aScopeObject,
				method: aMethod,
				arguments: aArguments,
				framesDelay: framesDelay
			};
			
			mDoLaterMethods.push(doLaterMethodDescriptor);
			
			mOnEnterFrameBeacon.addEventListener(Event.ENTER_FRAME, onBeaconEnterFrame);
		}
			
		private static function onBeaconEnterFrame() : void 
		{
			if(mDoLaterMethods.length == 0)
			{
				mOnEnterFrameBeacon.removeEventListener(Event.ENTER_FRAME, onBeaconEnterFrame);
			}
			
			var doLaterMethodDescriptor : Object;
			for (var i : Number = 0; i < mDoLaterMethods.length; i++)
			{
				doLaterMethodDescriptor = mDoLaterMethods[i];
				
				doLaterMethodDescriptor.framesDelay--;
				if(doLaterMethodDescriptor.framesDelay <= 0)
				{
					doLaterMethodDescriptor.method.apply(
						doLaterMethodDescriptor.scopeObject, 
						doLaterMethodDescriptor.arguments);
					mDoLaterMethods.splice(i, 1);
				}
			}
		}
	}
}